// Fill out your copyright notice in the Description page of Project Settings.

#include "GameSettingsManager.h"
#include "Engine/GameInstance.h"
#include "Kismet/GameplayStatics.h"

// 定义默认设置值
#define DEFAULT_WALK_SPEED 600.0f
#define DEFAULT_SPRINT_SPEED 1200.0f
#define DEFAULT_CAMERA_SENSITIVITY 1.0f

// 设置配置文件名
#define SETTINGS_CONFIG_FILE TEXT("GameSettings.ini")

// 设置配置节名称
#define SETTINGS_CONFIG_SECTION TEXT("GameSettings")

// 设置配置键名
#define SETTINGS_WALK_SPEED_KEY TEXT("WalkSpeed")
#define SETTINGS_SPRINT_SPEED_KEY TEXT("SprintSpeed")
#define SETTINGS_CAMERA_SENSITIVITY_KEY TEXT("CameraSensitivity")

void UGameSettingsManager::Initialize(FSubsystemCollectionBase& Collection)
{
    Super::Initialize(Collection);

    // 使用Winston日志记录子系统初始化
    FWinstonLogger::Get().Info(TEXT("GameSettingsManager"), TEXT("Initializing game settings manager"));

    // 设置默认值
    WalkSpeed = DEFAULT_WALK_SPEED;
    SprintSpeed = DEFAULT_SPRINT_SPEED;
    CameraSensitivity = DEFAULT_CAMERA_SENSITIVITY;

    // 加载保存的设置
    LoadSettings();

    // 应用设置
    ApplySettings();

    // 记录初始化完成
    FWinstonLogger::Get().Debug(TEXT("GameSettingsManager"), TEXT("Game settings manager initialized"));
}

void UGameSettingsManager::Deinitialize()
{
    // 使用Winston日志记录子系统关闭
    FWinstonLogger::Get().Info(TEXT("GameSettingsManager"), TEXT("Deinitializing game settings manager"));

    // 保存设置
    SaveSettings();

    Super::Deinitialize();
}

UGameSettingsManager* UGameSettingsManager::Get(const UObject* WorldContextObject)
{
    if (!WorldContextObject)
    {
        FWinstonLogger::Get().Error(TEXT("GameSettingsManager"), TEXT("Invalid world context object"));
        return nullptr;
    }

    // 获取游戏实例
    UGameInstance* GameInstance = WorldContextObject->GetWorld()->GetGameInstance();
    if (!GameInstance)
    {
        FWinstonLogger::Get().Error(TEXT("GameSettingsManager"), TEXT("Failed to get game instance"));
        return nullptr;
    }

    // 获取游戏设置管理器子系统
    UGameSettingsManager* SettingsManager = GameInstance->GetSubsystem<UGameSettingsManager>();
    if (!SettingsManager)
    {
        FWinstonLogger::Get().Error(TEXT("GameSettingsManager"), TEXT("Failed to get game settings manager"));
        return nullptr;
    }

    return SettingsManager;
}

void UGameSettingsManager::SetMovementSpeeds(float NewWalkSpeed, float NewSprintSpeed)
{
    // 验证输入值
    if (NewWalkSpeed < 0.0f)
    {
        FWinstonLogger::Get().Warning(TEXT("GameSettingsManager"), TEXT("Invalid walk speed: %f, using default"), NewWalkSpeed);
        NewWalkSpeed = DEFAULT_WALK_SPEED;
    }

    if (NewSprintSpeed < 0.0f)
    {
        FWinstonLogger::Get().Warning(TEXT("GameSettingsManager"), TEXT("Invalid sprint speed: %f, using default"), NewSprintSpeed);
        NewSprintSpeed = DEFAULT_SPRINT_SPEED;
    }

    // 更新设置
    WalkSpeed = NewWalkSpeed;
    SprintSpeed = NewSprintSpeed;

    // 记录设置变更
    FWinstonLogger::Get().Debug(TEXT("GameSettingsManager"), TEXT("Movement speeds updated - Walk: %f, Sprint: %f"), WalkSpeed, SprintSpeed);

    // 应用设置
    ApplySettings();

    // 保存设置
    SaveSettings();
}

float UGameSettingsManager::GetWalkSpeed() const
{
    return WalkSpeed;
}

float UGameSettingsManager::GetSprintSpeed() const
{
    return SprintSpeed;
}

void UGameSettingsManager::SetCameraSensitivity(float NewSensitivity)
{
    // 验证输入值
    if (NewSensitivity < 0.1f)
    {
        FWinstonLogger::Get().Warning(TEXT("GameSettingsManager"), TEXT("Invalid camera sensitivity: %f, using default"), NewSensitivity);
        NewSensitivity = DEFAULT_CAMERA_SENSITIVITY;
    }

    // 更新设置
    CameraSensitivity = NewSensitivity;

    // 记录设置变更
    FWinstonLogger::Get().Debug(TEXT("GameSettingsManager"), TEXT("Camera sensitivity updated: %f"), CameraSensitivity);

    // 应用设置
    ApplySettings();

    // 保存设置
    SaveSettings();
}

float UGameSettingsManager::GetCameraSensitivity() const
{
    return CameraSensitivity;
}

void UGameSettingsManager::LoadSettings()
{
    // 使用Winston日志记录加载设置
    FWinstonLogger::Get().Debug(TEXT("GameSettingsManager"), TEXT("Loading settings"));

    // 获取配置文件路径
    FString ConfigFilePath = FPaths::ProjectConfigDir() / SETTINGS_CONFIG_FILE;

    // 加载配置文件
    GConfig->GetFloat(*SETTINGS_CONFIG_SECTION, *SETTINGS_WALK_SPEED_KEY, WalkSpeed, ConfigFilePath);
    GConfig->GetFloat(*SETTINGS_CONFIG_SECTION, *SETTINGS_SPRINT_SPEED_KEY, SprintSpeed, ConfigFilePath);
    GConfig->GetFloat(*SETTINGS_CONFIG_SECTION, *SETTINGS_CAMERA_SENSITIVITY_KEY, CameraSensitivity, ConfigFilePath);

    // 记录加载的设置
    FWinstonLogger::Get().Debug(TEXT("GameSettingsManager"), 
        TEXT("Settings loaded - Walk: %f, Sprint: %f, Sensitivity: %f"), 
        WalkSpeed, SprintSpeed, CameraSensitivity);
}

void UGameSettingsManager::SaveSettings()
{
    // 使用Winston日志记录保存设置
    FWinstonLogger::Get().Debug(TEXT("GameSettingsManager"), TEXT("Saving settings"));

    // 获取配置文件路径
    FString ConfigFilePath = FPaths::ProjectConfigDir() / SETTINGS_CONFIG_FILE;

    // 确保配置目录存在
    FPlatformFileManager::Get().GetPlatformFile().CreateDirectoryTree(*FPaths::ProjectConfigDir());

    // 保存配置文件
    GConfig->SetFloat(*SETTINGS_CONFIG_SECTION, *SETTINGS_WALK_SPEED_KEY, WalkSpeed, ConfigFilePath);
    GConfig->SetFloat(*SETTINGS_CONFIG_SECTION, *SETTINGS_SPRINT_SPEED_KEY, SprintSpeed, ConfigFilePath);
    GConfig->SetFloat(*SETTINGS_CONFIG_SECTION, *SETTINGS_CAMERA_SENSITIVITY_KEY, CameraSensitivity, ConfigFilePath);

    // 保存到磁盘
    GConfig->Flush(false, ConfigFilePath);

    // 记录保存的设置
    FWinstonLogger::Get().Debug(TEXT("GameSettingsManager"), 
        TEXT("Settings saved - Walk: %f, Sprint: %f, Sensitivity: %f"), 
        WalkSpeed, SprintSpeed, CameraSensitivity);
}

void UGameSettingsManager::ApplySettings()
{
    // 使用Winston日志记录应用设置
    FWinstonLogger::Get().Debug(TEXT("GameSettingsManager"), TEXT("Applying settings"));

    // 这里可以添加将设置应用到游戏系统的代码
    // 例如，可以获取所有玩家角色并更新其移动速度
    // 或者更新相机控制器的灵敏度设置
    
    // 注意：在实际应用中，可能需要通过事件系统或其他方式通知相关系统设置已变更
}